/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.user.rest;


import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import co.yixiang.api.ApiResult;
import co.yixiang.api.YshopException;
import co.yixiang.common.bean.LocalUser;
import co.yixiang.common.interceptor.AuthCheck;
import co.yixiang.constant.ShopConstants;
import co.yixiang.enums.BillDetailEnum;
import co.yixiang.enums.BillEnum;
import co.yixiang.logging.aop.log.AppLog;
import co.yixiang.modules.product.domain.YxPrize;
import co.yixiang.modules.product.domain.YxPrizeDetail;
import co.yixiang.modules.product.domain.YxPrizeRecord;
import co.yixiang.modules.product.service.YxPrizeDetailService;
import co.yixiang.modules.product.service.YxPrizeRecordService;
import co.yixiang.modules.product.service.YxPrizeService;
import co.yixiang.modules.shop.service.YxSystemConfigService;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.domain.YxUserAddress;
import co.yixiang.modules.user.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

import static co.yixiang.constant.SystemConfigConstants.YSHOP_SHOW_RECHARGE;

/**
 * <p>
 * 用户等级 前端控制器
 * </p>
 *
 * @author hupeng
 * @since 2019-12-06
 */
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(value = "用户等级", tags = "用户:用户等级", description = "用户等级")
public class YxPrizeController {

    private final YxUserService userService;
    private final YxPrizeService yxPrizeService;
    private final YxPrizeDetailService yxPrizeDetailService;
    private final YxSystemConfigService systemConfigService;
    private final YxPrizeRecordService yxPrizeRecordService;
    private final YxUserBillService yxUserBillService;
    private final YxUserAddressService userAddressService;

    /**
    * 抽奖开始
    */
    @AuthCheck
    @GetMapping("/prize/begin/{id}")
    @ApiOperation(value = "抽奖开始",notes = "抽奖开始")
    public ApiResult<Object> getLevelInfo(@PathVariable String id){
        Long uid = LocalUser.getUser().getUid();
        YxUser user =userService.getById(uid);
        String hasPrizeCount ="Y";
        Map<String,Object> mapTemp = Maps.newHashMap();
        YxPrize prize =yxPrizeService.getById(Long.valueOf(id));
        if(user.getPrizeCount()>0){
            List<YxPrizeDetail> detailList =yxPrizeDetailService.list(
                    new LambdaQueryWrapper<YxPrizeDetail>().eq(YxPrizeDetail::getPrizeId,Long.valueOf(id)));
            List<Double> orignalRates = new ArrayList<Double>(detailList.size());
            /*for (YxPrizeDetail detail : detailList) {
                double weight = detail.getWeight();
                if (weight < 0) {
                    weight = 0;
                }
                orignalRates.add(weight);
            }*/
            Map<String,Object> map = lottery(detailList,user);
            user =userService.getById(uid);
            if(user.getPrizeCount()>0){
                map.put("hasPrizeCount","Y");
            }else{
                map.put("hasPrizeCount","N");
            }
            map.put("isShow",prize.getIsShow());
            return ApiResult.ok(map);
        }else{
            mapTemp.put("hasPrizeCount","N");
            mapTemp.put("isShow",prize.getIsShow());
            mapTemp.put("tips","您的抽奖次数为0,无法进行抽奖");
            return ApiResult.ok(mapTemp);
        }
    }

    /**
     * 进入抽奖页面
     */
    @AuthCheck
    @GetMapping("/prize/open/{id}")
    @ApiOperation(value = "进入抽奖页面",notes = "进入抽奖页面")
    public ApiResult<Object> userBalance(@PathVariable String id){
        YxUser yxUser = LocalUser.getUser();
        YxUser user =userService.getById(yxUser.getUid());
        String hasPrizeCount ="Y";
        Map<String,Object> map = Maps.newHashMap();
        if(user.getPrizeCount()>0){
            map.put("hasPrizeCount",hasPrizeCount);
        }else{
            map.put("hasPrizeCount","N");
        }
        if(ObjectUtil.isNull(id)){
            id="1";
        }
        List<YxPrizeDetail> detailList =yxPrizeDetailService.list(new LambdaQueryWrapper<YxPrizeDetail>().eq(YxPrizeDetail::getPrizeId,Long.valueOf(id)));
        List<YxPrizeRecord> recordList =yxPrizeRecordService.list(new LambdaQueryWrapper<YxPrizeRecord>().eq(YxPrizeRecord::getPrizeId,Long.valueOf(id)).orderByDesc(YxPrizeRecord::getId).last("limit 0,10"));
        YxPrize prize =yxPrizeService.getById(Long.valueOf(id));
        map.put("recordList",recordList);
        map.put("prizeList",detailList);
        map.put("prizeState",prize.getIsShow());
        return ApiResult.ok(map);
    }

    /**
     * 生成抽奖记录
     */
    @AuthCheck
    @GetMapping("/prize/record/{id}")
    @ApiOperation(value = "生成抽奖记录",notes = "生成抽奖记录")
    public ApiResult<Object> record(@PathVariable String id){
        YxUser user = LocalUser.getUser();
        YxUser yxUser =userService.getById(user.getUid());
        Map<String,Object> map = Maps.newHashMap();
        YxPrizeDetail detail =yxPrizeDetailService.getById(Long.valueOf(id));
        YxPrize prize =yxPrizeService.getById(detail.getPrizeId());
        YxPrizeRecord record = new YxPrizeRecord();
        record.setTitle(detail.getName());
        record.setUid(yxUser.getUid());
        record.setType(detail.getPrizeType());
        record.setNumber(detail.getValue());
        record.setNickname(yxUser.getNickname());
        record.setPhone(yxUser.getPhone());
        record.setPrizeEndTime(prize.getEndDate());
        record.setPrizeId(prize.getId());
        record.setPrizeImage(detail.getPrizeImage());
        record.setPrizeStatus(0);
        record.setPrizeDetailId(detail.getId());
        if(detail.getPrizeType()==1){
            record.setPrizeStatus(1);
            //扣减当前用户余额
            BigDecimal toUsertotalSum =yxUser.getNowMoney().add(detail.getValue());
            BigDecimal fromUsertotalSum = new BigDecimal("0");
            yxUserBillService.expend4traderCommission(new Long(0),yxUser.getUid(),"15", BillDetailEnum.CATEGORY_1.getValue(),
                    BillDetailEnum.TYPE_3.getValue(),detail.getValue().doubleValue(),fromUsertotalSum.doubleValue(), "抽奖获赠积分",yxUser.getPhone(), BillEnum.PM_0.getValue());
//增加目标用户余额
            yxUserBillService.expend4traderCommission(yxUser.getUid(),new Long(0),"15", BillDetailEnum.CATEGORY_1.getValue(),
                    BillDetailEnum.TYPE_2.getValue(),detail.getValue().doubleValue(),toUsertotalSum.doubleValue(), "抽奖获赠积分","公司转账", BillEnum.PM_1.getValue());
            userService.incMoney(yxUser.getUid(),detail.getValue());
        }
        yxPrizeRecordService.save(record);
        List<YxPrizeRecord> recordList =yxPrizeRecordService.list(new LambdaQueryWrapper<YxPrizeRecord>().eq(YxPrizeRecord::getPrizeId,detail.getPrizeId()).orderByDesc(YxPrizeRecord::getId).last("limit 0,10"));
        map.put("recordList",recordList);
        return ApiResult.ok(map);
    }

    /**
     * 抽奖
     *
     * @param detailList 原始的概率列表，保证顺序和实际物品对应
     * @return 物品的索引
     */
    public Map<String,Object> lottery(List<YxPrizeDetail> detailList,YxUser user) {
        Map<String,Object> map = new LinkedHashMap<>();
        int size = detailList.size();


        // 计算总概率，这样可以保证不一定总概率是1
        double sumRate = 0d;
        for (YxPrizeDetail detail : detailList) {
            if(detail.getStock()>0 && detail.getIsAppoint() !=1) {
                sumRate += detail.getWeight().doubleValue();
            }
        }
        //权重获取方法
        Random random =new Random();
        double n = random.nextDouble();
        double m = 0d;
        //String prizeUid =systemConfigService.getData(ShopConstants.PRIZE_UID);
        String result ="N";
        if(detailList.size()>0){
            String isUid ="N";
            for (int i = 0; i < detailList.size(); i++) {
                YxPrizeDetail detail = detailList.get(i);
                if(detail.getStock()>0 &&detail.getIsAppoint() == 1) {
                    if (ObjectUtil.isNotEmpty(detail.getPrizeUids())) {
                        String[] tempUids = detail.getPrizeUids().split(",");
                        for (int j = 0; j < tempUids.length; j++) {
                            if (Integer.valueOf(tempUids[j]) == user.getUid().intValue()) {
                                isUid = "Y";
                                break;
                            }
                        }
                    }
                    if("Y".equals(isUid)){
                        map.put("orignalIndex", i);
                        map.put("detail", detail);
                        detail.setStock(detail.getStock()-1);
                        yxPrizeDetailService.updateById(detail);
                        user.setPrizeCount(user.getPrizeCount()-1);
                        userService.updateById(user);
                        result ="Y";
                        break;
                    }
                }
            }
        }
        if("N".equals(result)) {
            if (detailList.size() > 0) {
                for (int i = 0; i < detailList.size(); i++) {
                    YxPrizeDetail detail = detailList.get(i);
                    double temp = detail.getWeight().doubleValue() / sumRate;// 计算物品在总概率的基础下的概率情况
                    BigDecimal weight = new BigDecimal(temp).setScale(2, BigDecimal.ROUND_UP).add(new BigDecimal(m));
                    if (detail.getStock() > 0) {
                            if (detail.getIsAppoint() != 1) {
                                if (new BigDecimal(n).compareTo(new BigDecimal(m)) != -1
                                        && weight.compareTo(new BigDecimal(n)) == 1 && detail.getWeight().compareTo(new BigDecimal(0)) == 1) {
                                    map.put("orignalIndex", i);
                                    map.put("detail", detail);
                                    detail.setStock(detail.getStock() - 1);
                                    yxPrizeDetailService.updateById(detail);
                                    user.setPrizeCount(user.getPrizeCount() - 1);
                                    userService.updateById(user);
                                    break;
                                }
                                m = m + detail.getWeight().doubleValue() / sumRate;
                            }
                    }
                }
            }
        }
        return map;
    }

    /**
     * 抽奖明细列表
     */
    @AuthCheck
    @GetMapping("/prizeRecord/list/{prizeState}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "prizeState", value = "prizeState", paramType = "query", dataType = "int",required = true),
            @ApiImplicitParam(name = "page", value = "页码,默认为1", paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "limit", value = "页大小,默认为10", paramType = "query", dataType = "int")
    })
    @ApiOperation(value = "抽奖明细列表",notes = "抽奖明细列表")
    public ApiResult<Map<String,Object>> getDetailList(@PathVariable int prizeState,@RequestParam(value = "page",defaultValue = "1") int page,
                                                       @RequestParam(value = "limit",defaultValue = "10") int limit){
        Map<String,Object> map = Maps.newHashMap();
        YxUser user = LocalUser.getUser();
        List<YxPrizeRecord> prizeRecordList =yxPrizeRecordService.getPrizeRecordList(user.getUid(),prizeState,page,limit);
        map.put("prizeRecordList",prizeRecordList);
        return  ApiResult.ok(map);
    }

    @AppLog(value = "抽奖活动兑奖提交信息", type = 1)
    @AuthCheck
    @PostMapping("/prizeRecord/update/{id}/{addressId}")
    @ApiOperation(value = "抽奖活动兑奖提交信息",notes = "抽奖活动兑奖提交信息")
    public ApiResult<String> updatePrizeRecord(@Validated @PathVariable String id, @PathVariable String addressId){
        YxPrizeRecord record = yxPrizeRecordService.getById(Long.valueOf(id));
        YxUserAddress userAddress =userAddressService.getById(Long.valueOf(addressId));
        record.setUserAddress(userAddress.getProvince()+" "+userAddress.getCity()+
                " "+userAddress.getDistrict()+" "+userAddress.getDetail());
        record.setPrizeStatus(1);
        record.setPrizeTime(new Date());
        record.setRealName(userAddress.getRealName());
        record.setUserPhone(userAddress.getPhone());
        yxPrizeRecordService.updateById(record);
        return ApiResult.ok("提交成功");
    }

}

